const { TriggerDao } = require('../dao/trigger');
const { Sandbox } = require('../sandbox');
const context = require('../globalContext');

/* ======== Action Logic ============ */
const TriggerAction = {

    async addOne({ script, note }) {
        console.log('Put From TriggerAction.getOne');
        return new Promise((reslove) => {
            if (!this.valiOne(script)) return reslove(false);
            TriggerDao.addOne({ script, note }, () => { reslove(true) });
        });
    },

    async getOne(id) {
        console.log('Get From TriggerAction.getOne', id);
        return new Promise(reslove => TriggerDao.getOne(id, row => reslove(row)));
    },

    async getList() {
        console.log('Get From TriggerAction.getList');
        return new Promise(reslove => TriggerDao.getList(rows => reslove(rows)));
    },

    delOne(id) {
        console.log('Delete From TriggerAction.delOne', id);
        TriggerDao.delOne(id);
    },

    altOne({ id, script, note }) {
        console.log('Patch From TriggerAction.altOne', id);
        return new Promise((reslove) => {
            if (!this.valiOne(script)) return reslove(false);
            TriggerDao.altOne({ id, script, note }, () => { reslove(true) } );
        });
    },

    valiOne(script) {
        // console.log('Test whether Script is Legal or not')
        console.log('Validate whether the script is legal');
        const sb = new Sandbox({ sc: script, ctx: context });
        return sb.testScript();
    },

    testOne(script) {
        console.log('Test the condition is trigger');
        const sb = new Sandbox({ sc: script, ctx: context });
        return sb.runScript();
    }

}

/* ==== Router Regist  ============ */

const TriggerRouter = router => {

    router.put('/action/trigger', async (ctx, next) => {
        console.log('PUT trigger');
        let { script, note } = ctx.request.body;
        // Decode From Base64 to Save.
        script = Buffer.from(script, 'base64').toString();
        let rtn = await TriggerAction.addOne({ script, note });
        ctx.status = rtn ? 200 : 400;
        ctx.body = rtn ? 'OK' : 'FAILED';
        next();
    });

    router.get('/action/trigger/:id', async (ctx, next) => {
        console.log('GET tringger ID :# ', ctx.params.id);
        let row = await TriggerAction.getOne(ctx.params.id);
        // Encode Into Base64 to Transport.
        if (row) {
            row.script = Buffer.from(row.script).toString('base64');
        } else {
            row = { ID: 0 };
        }
        ctx.set('Content-Type', 'application/json');
        ctx.body = row;
        next();
    });

    router.get('/action/trigger', async (ctx, next) => {
        console.log('GET triggers ');
        let rows = await TriggerAction.getList();
        ctx.set('Content-Type', 'application/json');
        ctx.body = rows;
        next();
    });

    router.delete('/action/trigger/:id', async (ctx, next) => {
        console.log('DELETE trigger :# ', ctx.params.id);
        TriggerAction.delOne(ctx.params.id);
        ctx.status = 204;
        ctx.body = 'OK';
        next();
    });

    router.patch('/action/trigger/:id', async (ctx, next) => {
        console.log('PATCH trigger ID :# ', ctx.params.id);
        let { script, note } = ctx.request.body;
        script = Buffer.from(script, 'base64').toString();
        let rtn = await TriggerAction.altOne({ "id": ctx.params.id, "note": note, "script": script });
        ctx.status = rtn ? 200 : 400;
        ctx.body = rtn ? 'OK' : 'FAILED';
        next();
    });

    router.post('/action/trigger/vali', async (ctx, next) => {
        console.log('POST trigger :# ');
        let { script } = ctx.request.body;
        script = Buffer.from(script, 'base64').toString();
        let flag = TriggerAction.valiOne(script);
        ctx.set('Content-Type', 'application/json');
        ctx.body = { flag }
        ctx.status = 200;
        next();
    });

    router.post('/action/trigger/test', async (ctx, next) => {
        console.log('POST trigger :# ');
        let { script } = ctx.request.body;
        script = Buffer.from(script, 'base64').toString();
        let flag = TriggerAction.testOne(script);
        ctx.set('Content-Type', 'application/json');
        ctx.body = { flag }
        ctx.status = 200;
        next();
    });
}

module.exports.TriggerRouter = TriggerRouter;